<template>
  <div class="training-photo-list">
    <el-card class="photo-card">
      <template #header>
        <div class="card-header">
          <span>训练照片管理</span>
          <div class="header-actions">
            <el-date-picker
              v-model="dateRange"
              type="daterange"
              range-separator="至"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              format="YYYY-MM-DD"
              value-format="YYYY-MM-DD"
              style="width: 250px; margin-right: 10px"
              @change="handleSearch"
            />
            <el-select
              v-model="searchForm.memberId"
              placeholder="选择会员"
              clearable
              filterable
              style="width: 200px; margin-right: 10px"
              @change="handleSearch"
            >
              <el-option
                v-for="member in memberOptions"
                :key="member.id"
                :label="member.name"
                :value="member.id"
              />
            </el-select>
            <el-button type="primary" @click="handleUpload">上传照片</el-button>
            <el-button @click="handleRefresh">刷新</el-button>
          </div>
        </div>
      </template>

      <el-table
        :data="photoList"
        v-loading="loading"
        style="width: 100%"
        row-key="id"
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="55" />
        <el-table-column prop="id" label="ID" width="80" />
        <el-table-column label="照片预览" width="150">
          <template #default="scope">
            <div class="photo-preview">
              <el-image
                :src="scope.row.fileUrl"
                :preview-src-list="[scope.row.fileUrl]"
                fit="cover"
                class="preview-image"
              />
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="member.name" label="会员" width="120" />
        <el-table-column prop="photoDate" label="拍摄日期" width="120" />
        <el-table-column prop="bodyPart" label="身体部位" width="100">
          <template #default="scope">
            <el-tag :type="getBodyPartTagType(scope.row.bodyPart)">
              {{ formatBodyPart(scope.row.bodyPart) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="weight" label="体重(kg)" width="100">
          <template #default="scope">
            <span v-if="scope.row.weight">{{ scope.row.weight }}</span>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column prop="bodyFat" label="体脂率(%)" width="100">
          <template #default="scope">
            <span v-if="scope.row.bodyFat">{{ scope.row.bodyFat }}</span>
            <span v-else>-</span>
          </template>
        </el-table-column>
        <el-table-column prop="isPublic" label="是否公开" width="100">
          <template #default="scope">
            <el-tag :type="scope.row.isPublic ? 'success' : 'info'">
              {{ scope.row.isPublic ? '是' : '否' }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createdAt" label="上传时间" width="180" />
        <el-table-column label="操作" width="200" fixed="right">
          <template #default="scope">
            <el-button size="small" @click="handleView(scope.row)">查看</el-button>
            <el-button size="small" type="danger" @click="handleDelete(scope.row)">删除</el-button>
          </template>
        </el-table-column>
      </el-table>

      <div class="table-actions">
        <el-button
          type="danger"
          :disabled="selectedPhotos.length === 0"
          @click="handleBatchDelete"
        >
          批量删除 ({{ selectedPhotos.length }})
        </el-button>
      </div>

      <div class="pagination">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.pageSize"
          :page-sizes="[10, 20, 50, 100]"
          :total="pagination.total"
          layout="total, sizes, prev, pager, next, jumper"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </el-card>

    <!-- 上传照片对话框 -->
    <el-dialog
      v-model="uploadDialogVisible"
      title="上传训练照片"
      width="600px"
    >
      <el-form
        ref="uploadFormRef"
        :model="uploadForm"
        :rules="uploadRules"
        label-width="100px"
      >
        <el-form-item label="照片" prop="file">
          <el-upload
            class="photo-uploader"
            :show-file-list="false"
            :auto-upload="false"
            :on-change="handlePhotoChange"
          >
            <img
              v-if="uploadForm.imageUrl"
              :src="uploadForm.imageUrl"
              class="photo"
            />
            <el-icon v-else class="photo-uploader-icon">
              <Plus />
            </el-icon>
          </el-upload>
        </el-form-item>

        <el-form-item label="拍摄日期" prop="photoDate">
          <el-date-picker
            v-model="uploadForm.photoDate"
            type="date"
            placeholder="选择拍摄日期"
            format="YYYY-MM-DD"
            value-format="YYYY-MM-DD"
            style="width: 100%"
          />
        </el-form-item>

        <el-form-item label="身体部位" prop="bodyPart">
          <el-select
            v-model="uploadForm.bodyPart"
            placeholder="选择身体部位"
            style="width: 100%"
            clearable
          >
            <el-option label="正面" value="FRONT" />
            <el-option label="背面" value="BACK" />
            <el-option label="侧面" value="SIDE" />
            <el-option label="其他" value="OTHER" />
          </el-select>
        </el-form-item>

        <el-form-item label="体重(kg)" prop="weight">
          <el-input-number
            v-model="uploadForm.weight"
            :min="0"
            :max="500"
            :precision="2"
            style="width: 100%"
          />
        </el-form-item>

        <el-form-item label="体脂率(%)" prop="bodyFat">
          <el-input-number
            v-model="uploadForm.bodyFat"
            :min="0"
            :max="100"
            :precision="2"
            style="width: 100%"
          />
        </el-form-item>

        <el-form-item label="描述" prop="description">
          <el-input
            v-model="uploadForm.description"
            type="textarea"
            :rows="3"
            placeholder="请输入描述"
            :maxlength="200"
            show-word-limit
          />
        </el-form-item>

        <el-form-item label="是否公开" prop="isPublic">
          <el-switch v-model="uploadForm.isPublic" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="uploadDialogVisible = false">取消</el-button>
          <el-button
            type="primary"
            @click="submitUpload"
            :loading="uploadLoading"
          >
            上传
          </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 照片详情对话框 -->
    <el-dialog
      v-model="detailDialogVisible"
      title="照片详情"
      width="800px"
    >
      <div class="photo-detail">
        <el-row :gutter="20">
          <el-col :span="12">
            <el-image
              :src="currentPhoto.fileUrl"
              :preview-src-list="[currentPhoto.fileUrl]"
              fit="contain"
              style="width: 100%; height: 400px"
            />
          </el-col>
          <el-col :span="12">
            <el-descriptions :column="1" border>
              <el-descriptions-item label="照片ID">{{ currentPhoto.id }}</el-descriptions-item>
              <el-descriptions-item label="会员">会员ID: {{ currentPhoto.memberId }}</el-descriptions-item>
              <el-descriptions-item label="拍摄日期">{{ currentPhoto.photoDate }}</el-descriptions-item>
              <el-descriptions-item label="身体部位">
                <el-tag :type="getBodyPartTagType(currentPhoto.bodyPart)">
                  {{ formatBodyPart(currentPhoto.bodyPart) }}
                </el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="体重(kg)">
                <span v-if="currentPhoto.weight">{{ currentPhoto.weight }}</span>
                <span v-else>-</span>
              </el-descriptions-item>
              <el-descriptions-item label="体脂率(%)">
                <span v-if="currentPhoto.bodyFat">{{ currentPhoto.bodyFat }}</span>
                <span v-else>-</span>
              </el-descriptions-item>
              <el-descriptions-item label="是否公开">
                <el-tag :type="currentPhoto.isPublic ? 'success' : 'info'">
                  {{ currentPhoto.isPublic ? '是' : '否' }}
                </el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="描述">
                <div class="description-content">
                  {{ currentPhoto.description || '-' }}
                </div>
              </el-descriptions-item>
              <el-descriptions-item label="上传时间">{{ currentPhoto.createdAt }}</el-descriptions-item>
            </el-descriptions>
          </el-col>
        </el-row>
      </div>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="detailDialogVisible = false">关闭</el-button>
          <el-button type="primary" @click="handleDownload(currentPhoto)">下载</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { UploadFile } from 'element-plus'
import type { TrainingPhoto, UploadTrainingPhotoRequest } from '@/types/api/file'
import { trainingPhotoApi } from '@/api/modules/file'
import { preventDuplicateSubmit, formUtils } from '@/utils'

// 表格相关
const loading = ref(false)
const photoList = ref<TrainingPhoto[]>([])
const currentPhoto = ref<TrainingPhoto>({
  id: 0,
  memberId: 0,
  fileId: 0,
  fileUrl: '',
  photoDate: '',
  bodyPart: 'FRONT',
  weight: 0,
  bodyFat: 0,
  description: '',
  isPublic: false,
  createdAt: '',
  updatedAt: ''
})

// 搜索表单
const dateRange = ref<[string, string]>(['', ''])
const searchForm = reactive({
  memberId: undefined as number | undefined
})

// 分页相关
const pagination = reactive({
  page: 1,
  pageSize: 10,
  total: 0
})

// 对话框相关
const uploadDialogVisible = ref(false)
const detailDialogVisible = ref(false)
const uploadLoading = ref(false)
const uploadFormRef = ref()

// 上传表单数据
const uploadForm = reactive({
  file: null as File | null,
  imageUrl: '',
  photoDate: '',
  bodyPart: undefined as 'FRONT' | 'BACK' | 'SIDE' | 'OTHER' | undefined,
  weight: undefined as number | undefined,
  bodyFat: undefined as number | undefined,
  description: '',
  isPublic: false
})

// 选中的照片
const selectedPhotos = ref<TrainingPhoto[]>([])

// 模拟会员选项
const memberOptions = ref([
  { id: 1, name: '张三' },
  { id: 2, name: '李四' },
  { id: 3, name: '王五' }
])

// 表单验证规则
const uploadRules = {
  file: [
    { required: true, message: '请上传照片', trigger: 'change' }
  ],
  photoDate: [
    { required: true, message: '请选择拍摄日期', trigger: 'change' }
  ]
}

// 获取训练照片列表
const getTrainingPhotoList = async () => {
  try {
    loading.value = true
    const params: any = {
      page: pagination.page,
      pageSize: pagination.pageSize
    }

    if (searchForm.memberId) {
      params.memberId = searchForm.memberId
    }

    if (dateRange.value[0]) {
      params.startDate = dateRange.value[0]
    }

    if (dateRange.value[1]) {
      params.endDate = dateRange.value[1]
    }

    const response = await trainingPhotoApi.getTrainingPhotoList(params)
    photoList.value = response.data.data.list
    pagination.total = response.data.data.total
  } catch (error) {
    ElMessage.error('获取训练照片列表失败')
  } finally {
    loading.value = false
  }
}

// 搜索
const handleSearch = () => {
  pagination.page = 1
  getTrainingPhotoList()
}

// 刷新列表
const handleRefresh = () => {
  getTrainingPhotoList()
}

// 处理照片文件变化
const handlePhotoChange = (uploadFile: UploadFile) => {
  if (uploadFile.raw) {
    uploadForm.file = uploadFile.raw
    uploadForm.imageUrl = URL.createObjectURL(uploadFile.raw)
  }
}

// 上传照片
const handleUpload = () => {
  // 重置表单
  uploadForm.file = null
  uploadForm.imageUrl = ''
  uploadForm.photoDate = ''
  uploadForm.bodyPart = undefined
  uploadForm.weight = undefined
  uploadForm.bodyFat = undefined
  uploadForm.description = ''
  uploadForm.isPublic = false
  uploadDialogVisible.value = true
}

// 提交上传
const submitUpload = async () => {
  if (!uploadFormRef.value) return

  try {
    await uploadFormRef.value.validate()

    if (!uploadForm.file) {
      ElMessage.warning('请上传照片')
      return
    }

    // 使用防重复提交保护
    await preventDuplicateSubmit('upload_training_photo', async () => {
      uploadLoading.value = true

      try {
        const uploadData: UploadTrainingPhotoRequest = {
          file: uploadForm.file!,
          photoDate: uploadForm.photoDate,
          bodyPart: uploadForm.bodyPart,
          weight: uploadForm.weight,
          bodyFat: uploadForm.bodyFat,
          description: uploadForm.description,
          isPublic: uploadForm.isPublic
        }

        const res = await trainingPhotoApi.uploadTrainingPhoto(uploadData)
        ElMessage.success('照片上传成功')
        uploadDialogVisible.value = false
        getTrainingPhotoList()
      } catch (error: any) {
        ElMessage.error('照片上传失败')
        throw error // 重新抛出错误以确保防重复提交正确处理
      } finally {
        uploadLoading.value = false
      }
    })
  } catch (error: any) {
    // 防重复提交保护捕获的错误
    if (error.message === '请勿重复提交') {
      ElMessage.warning('请勿重复提交')
    }
  }
}

// 查看照片详情
const handleView = (row: TrainingPhoto) => {
  currentPhoto.value = row
  detailDialogVisible.value = true
}

// 删除照片
const handleDelete = async (row: TrainingPhoto) => {
  formUtils.handleDeleteConfirm('这张训练照片', async () => {
    await trainingPhotoApi.deleteTrainingPhoto(row.id)
    getTrainingPhotoList()
  }, {
    successMessage: '删除成功',
    errorMessage: '删除失败'
  })
}

// 批量删除照片
const handleBatchDelete = async () => {
  if (selectedPhotos.value.length === 0) {
    ElMessage.warning('请至少选择一张照片')
    return
  }

  formUtils.handleBatchDeleteConfirm(
    selectedPhotos.value.length,
    '照片',
    async () => {
      // 批量删除
      for (const photo of selectedPhotos.value) {
        await trainingPhotoApi.deleteTrainingPhoto(photo.id)
      }
      selectedPhotos.value = []
      getTrainingPhotoList()
    },
    {
      successMessage: '批量删除成功',
      errorMessage: '批量删除失败'
    }
  )
}

// 下载照片
const handleDownload = (row: TrainingPhoto) => {
  // 创建一个隐藏的a标签来下载照片
  const link = document.createElement('a')
  link.href = row.fileUrl
  link.download = `training_photo_${row.id}.jpg`
  link.style.display = 'none'
  document.body.appendChild(link)
  link.click()
  document.body.removeChild(link)
}

// 处理选中变化
const handleSelectionChange = (selection: TrainingPhoto[]) => {
  selectedPhotos.value = selection
}

// 分页相关方法
const handleSizeChange = (val: number) => {
  pagination.pageSize = val
  getTrainingPhotoList()
}

const handleCurrentChange = (val: number) => {
  pagination.page = val
  getTrainingPhotoList()
}

// 格式化身体部位
const formatBodyPart = (part?: string) => {
  const partMap: Record<string, string> = {
    'FRONT': '正面',
    'BACK': '背面',
    'SIDE': '侧面',
    'OTHER': '其他'
  }
  return part ? partMap[part] || part : '-'
}

// 获取身体部位标签类型
const getBodyPartTagType = (part?: string) => {
  const partMap: Record<string, string> = {
    'FRONT': 'primary',
    'BACK': 'success',
    'SIDE': 'warning',
    'OTHER': 'info'
  }
  return part ? partMap[part] || 'info' : 'info'
}

// 生命周期
onMounted(() => {
  getTrainingPhotoList()
})
</script>

<style scoped>
.training-photo-list {
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.table-actions {
  margin: 20px 0;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.photo-preview {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 120px;
  height: 120px;
}

.preview-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.photo-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.photo-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.photo-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}

.photo {
  width: 178px;
  height: 178px;
  display: block;
}

.photo-detail {
  margin-bottom: 20px;
}

.description-content {
  white-space: pre-wrap;
  line-height: 1.5;
}
</style>
